package com.wsoft.hr.pm.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wsoft.core.exception.Asserts;
import com.wsoft.core.utils.LoginUserUtil;
import com.wsoft.hr.pm.entity.*;
import com.wsoft.hr.pm.enums.ProcessCardTypeEnum;
import com.wsoft.hr.pm.enums.TargetTypeEnum;
import com.wsoft.hr.pm.mapper.HrPmMemberTemplateScoreMapper;
import com.wsoft.hr.pm.query.activity.member.template.score.MemberTemplateScopeScoreSaveQuery;
import com.wsoft.hr.pm.query.activity.member.template.score.MemberTemplateScoreSaveQuery;
import com.wsoft.hr.pm.query.activity.member.template.score.MemberTemplateTargetScoreSaveQuery;
import com.wsoft.hr.pm.service.*;
import com.wsoft.hr.pm.vo.member.template.score.ScoreHisVO;
import com.wsoft.hr.pm.vo.process.activity.ProcessActivityNodeVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 人员考核评分表 服务实现类
 * </p>
 *
 * @author zhanggukai
 * @since 2025年03月04日 10:38:00
 */
@Service
public class HrPmMemberTemplateScoreServiceImpl extends ServiceImpl<HrPmMemberTemplateScoreMapper, HrPmMemberTemplateScoreEntity> implements IHrPmMemberTemplateScoreService {

    @Resource
    private IHrPmMemberTemplateScopeScoreService scopeScoreService;

    @Resource
    private IHrPmMemberTemplateTargetScoreService targetScoreService;

    @Resource
    private IHrPmMemberTemplateService memberTemplateService;

    @Resource
    private IHrPmMemberTemplateTargetHisService memberTemplateTargetHisService;

    @Resource
    private IHrPmProcessActivityService processActivityService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveMemberTemplateScore(MemberTemplateScoreSaveQuery query) {
        //新增人员考核评分
        HrPmMemberTemplateScoreEntity entity = Convert.convert(HrPmMemberTemplateScoreEntity.class, query);
        HrPmMemberTemplateEntity memberTemplate = memberTemplateService.getById(query.getMemberTemplateId());
        ProcessActivityNodeVO nodeVO = processActivityService.getProcessActivityNode(memberTemplate.getScoreBusinessCode());
        if (ObjectUtil.isNotEmpty(nodeVO)){
            entity.setStep(nodeVO.getNodeType());
        }
        entity.setScoreMemberId(LoginUserUtil.getUserInfo().getLoginUserVO().getId());
        entity.setScoreMemberName(LoginUserUtil.getUserInfo().getLoginUserVO().getName());
        saveOrUpdate(entity);
        Long memberTemplateScoreId = entity.getId();
        //新增维度评分
        for (MemberTemplateScopeScoreSaveQuery item : query.getScopeScoreList()) {
            item.setMemberTemplateId(query.getMemberTemplateId());
            HrPmMemberTemplateScopeScoreEntity scopeScoreEntity = Convert.convert(HrPmMemberTemplateScopeScoreEntity.class, item);
            scopeScoreEntity.setMemberTemplateScoreId(memberTemplateScoreId);
            scopeScoreService.saveOrUpdate(scopeScoreEntity);
            if(CollUtil.isNotEmpty(item.getTargetScoreList())){
                //赋值模板id
                for (MemberTemplateTargetScoreSaveQuery targetScore: item.getTargetScoreList()) {
                    HrPmMemberTemplateTargetScoreEntity targetScoreEntity = Convert.convert(HrPmMemberTemplateTargetScoreEntity.class, targetScore);
                    targetScoreEntity.setMemberTemplateId(scopeScoreEntity.getMemberTemplateId());
                    targetScoreEntity.setMemberTemplateScoreId(memberTemplateScoreId);
                    checkScore(targetScore);
                    targetScoreService.saveOrUpdate(targetScoreEntity);
                }
            }
        }
        if (memberTemplate.getScoreStatus()==0){
            //评分人数
            QueryWrapper<HrPmMemberTemplateScoreEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(HrPmMemberTemplateScoreEntity::getMemberTemplateId, memberTemplate.getId())
                    .eq(HrPmMemberTemplateScoreEntity::getStep, ProcessCardTypeEnum.SELF_EVALUATION_CARD.getType());
            List<HrPmMemberTemplateScoreEntity> scoreList = list(queryWrapper);
            if (CollUtil.isEmpty(scoreList)) {
                return;
            }
            List<Long> collect = scoreList.stream().map(HrPmMemberTemplateScoreEntity::getId).collect(Collectors.toList());
            QueryWrapper<HrPmMemberTemplateTargetScoreEntity> targetScoreQuery = new QueryWrapper<>();
            targetScoreQuery.lambda().in(HrPmMemberTemplateTargetScoreEntity::getMemberTemplateScoreId,collect);
            long count = targetScoreService.count(targetScoreQuery);
            QueryWrapper<HrPmMemberTemplateTargetHisEntity> targetQuery = new QueryWrapper<>();
            targetQuery.lambda().eq(HrPmMemberTemplateTargetHisEntity::getMemberTemplateId, memberTemplate.getId());
            long targetCount = memberTemplateTargetHisService.count(targetQuery);
            if (count == targetCount){
                memberTemplateService.submitScoreStage(memberTemplate.getId());
            }
        }
    }

    @Override
    public List<ScoreHisVO> getScoreHis(Long memberTemplateId) {
        List<ScoreHisVO> hisVOList = new ArrayList<>();
        QueryWrapper<HrPmMemberTemplateScoreEntity> query = new QueryWrapper<>();
        query.lambda().eq(HrPmMemberTemplateScoreEntity::getMemberTemplateId, memberTemplateId);
        List<HrPmMemberTemplateScoreEntity> list = list(query);
        Map<String, List<HrPmMemberTemplateScoreEntity>> map = list.stream().collect(Collectors.groupingBy(HrPmMemberTemplateScoreEntity::getStep));
        if (CollUtil.isNotEmpty(map.get(ProcessCardTypeEnum.SELF_EVALUATION_CARD.getType()))) {
            List<HrPmMemberTemplateScoreEntity> dataList = map.get(ProcessCardTypeEnum.SELF_EVALUATION_CARD.getType());
            ScoreHisVO scoreHisVO = new ScoreHisVO();
            scoreHisVO.setStep(ProcessCardTypeEnum.SELF_EVALUATION_CARD.getType());
            scoreHisVO.setName(dataList.stream().map(HrPmMemberTemplateScoreEntity::getScoreMemberName).collect(Collectors.joining(",")));
            scoreHisVO.setScore(dataList.stream().map(HrPmMemberTemplateScoreEntity::getScore).reduce(BigDecimal.ZERO,BigDecimal::add));
            hisVOList.add(scoreHisVO);
        }
        if (CollUtil.isNotEmpty(map.get(ProcessCardTypeEnum.INVITATION_FOR_EVALUATION_CARD.getType()))) {
            List<HrPmMemberTemplateScoreEntity> collect = map.get(ProcessCardTypeEnum.INVITATION_FOR_EVALUATION_CARD.getType()).stream().sorted(Comparator.comparing(HrPmMemberTemplateScoreEntity::getCreateTime)).collect(Collectors.toList());
            collect.forEach(e->{
                ScoreHisVO scoreHisVO = new ScoreHisVO();
                scoreHisVO.setStep(ProcessCardTypeEnum.INVITATION_FOR_EVALUATION_CARD.getType());
                scoreHisVO.setName(e.getScoreMemberName());
                scoreHisVO.setScore(e.getScore());
                hisVOList.add(scoreHisVO);
            });
        }
        if (CollUtil.isNotEmpty(map.get(ProcessCardTypeEnum.SUPERIOR_RATING_CARD.getType()))) {
            List<HrPmMemberTemplateScoreEntity> collect = map.get(ProcessCardTypeEnum.SUPERIOR_RATING_CARD.getType()).stream().sorted(Comparator.comparing(HrPmMemberTemplateScoreEntity::getCreateTime)).collect(Collectors.toList());
            collect.forEach(e->{
                ScoreHisVO scoreHisVO = new ScoreHisVO();
                scoreHisVO.setStep(ProcessCardTypeEnum.SUPERIOR_RATING_CARD.getType());
                scoreHisVO.setName(e.getScoreMemberName());
                scoreHisVO.setScore(e.getScore());
                hisVOList.add(scoreHisVO);
            });
        }
            return hisVOList;
    }

    /**
     * 校验评分标准
     */
    private void checkScore(MemberTemplateTargetScoreSaveQuery targetScore){
        if (targetScore.getTargetType().equals(TargetTypeEnum.REFERENCE.getType())){
            if (BigDecimal.valueOf(targetScore.getScore()).compareTo(targetScore.getWeight())>0){
                Asserts.fail("基准内指标评分不能大于权重");
            }
        else {
            if (BigDecimal.valueOf(targetScore.getScore()).compareTo(BigDecimal.valueOf(targetScore.getTargetTypeValue()))>0){
                Asserts.fail("基准内指标评分不能大于上限");
            }
            }
        }
    }
}